﻿using JmShared;
using SuperSocket.SocketBase;
using SuperWebSocket;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using WebSocketServer.models;
using WebSocketServer.Utilities;

namespace WebSocketServer
{
    public class JiveClientSession : JsonWebSocketSession<JiveClientSession>
    {
        private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        public ChatClient ChatClient { get; set; }
        public bool IsLoggedIn { get; set; }
        public bool IsReadyToReceiveMessages { get; set; }
        public new JiveAppServer AppServer
        {
            get
            {
                return (JiveAppServer)base.AppServer;
            }
        }
        public bool SendFileSlice(FileSlice slice)
        {
            if (this.Connected && this.IsLoggedIn && this.IsReadyToReceiveMessages)
            {
                this.SendJsonMessage(ServerCommands.FileTransfer.ToString(), slice);
                return true;
            }
            return false;
        }
        public bool SendMessageQueue(MessageQueue queue)
        {
            if (this.Connected && this.IsLoggedIn && this.IsReadyToReceiveMessages)
            {

                this.SendJsonMessage(ServerCommands.MessageQueue.ToString(), queue);
                return true;
            }
            return false;
        }

        public bool SendLoginResponse(LoginResponse response)
        {
            if (this.Connected)
            {
                this.SendJsonMessage(ServerCommands.LoginResponse.ToString(), response);
                return true;
            }
            return false;
        }

        public bool SendServerInfoMessage(ServerInfoMessage msg)
        {
            if (this.Connected)
            {
                this.SendJsonMessage(ServerCommands.ServerInfoMessage.ToString(), msg);
                return true;
            }
            return false;
        }
        public bool SendEmoticon(ContactEmoticonTransfer emoticon)
        {
            if (this.Connected && this.IsLoggedIn)
            {
                this.SendJsonMessage(ServerCommands.CustomEmoticon.ToString(), emoticon);
                return true;
            }
            return false;
        }
        public bool SendAvatar(AvatarTransfer avatar)
        {
            if (this.Connected && this.IsLoggedIn)
            {
                this.SendJsonMessage(ServerCommands.Avatar.ToString(), avatar);
                return true;
            }
            return false;
        }
        public bool SendAvatarRequest(AvatarRequest request)
        {
            if (this.Connected && this.IsLoggedIn)
            {
                this.SendJsonMessage(ServerCommands.RequestAvatar.ToString(), request);
                return true;
            }
            return false;
        }
        public bool SendEmoticonRequest(EmoticonRequest request)
        {
            if (this.Connected && this.IsLoggedIn)
            {
                this.SendJsonMessage(ServerCommands.RequestEmoticon.ToString(), request);
                return true;
            }
            return false;
        }
        public bool SendMessage(ChatMessage msg)
        {
            if (this.Connected && this.IsLoggedIn && this.ChatClient.IsActive.GetValueOrDefault(true) == true && IsReadyToReceiveMessages)
            {
                this.SendJsonMessage(ServerCommands.Message.ToString(), msg);

                return true;
            }
            return false;
        }
        public bool SendDeviceStatus(DeviceStatus status)
        {
            if (this.Connected && this.IsLoggedIn && IsReadyToReceiveMessages)
            {
                this.SendJsonMessage(ServerCommands.DeviceStatusUpdate.ToString(), status);
                return true;
            }
            return false;
        }
        internal bool SendReceipt(ChatReceipt chatReceipt)
        {
            if (this.Connected && this.IsLoggedIn && IsReadyToReceiveMessages)
            {
                this.SendJsonMessage(ServerCommands.ChatReceipt.ToString(), chatReceipt);
                return true;
            }
            return false;

        }



        /// <summary>
        /// Send contact list to client.
        /// </summary>
        /// <param name="conn"></param>
        /// <param name="senderID"></param>
        public void SendClientList(bool refreshFromDatabase)
        {
            try
            {
                if (refreshFromDatabase)
                {
                    this.ChatClient.FriendsList = new HashSet<Friend>(DB.DbManager.ReadFriendsList(this.ChatClient.MemberID));

                }


                this.SendJsonMessage(ServerCommands.ClientList.ToString(), this.ChatClient.CreateClientList());

            }
            catch (Exception err)
            {
                log.Error("Error sending client list", err);
            }
        }



        internal void ReceiveEmoticon(ContactEmoticonTransfer emoticon)
        {
            try
            {
                if (emoticon == null) throw new ArgumentNullException("msg", "message is null");
                DB.DbManager.StoreCustomEmoticon(ChatClient.MemberID, emoticon);
                ChatClient.EmoticonDownloadQueue[emoticon.KeyWord] = true;
                log.Debug(string.Format("Setting emoticon {0} status to downloaded for {1}", emoticon.KeyWord, this.ChatClient.Username));
                if (!ChatClient.EmoticonDownloadQueue.Any(x => x.Value == false))
                {
                    ChatClient.WaitForEmoticonEvent.Set();
                    log.Debug(string.Format("Triggered WaitForEmoticonEvent for {0}", this.ChatClient.Username));
                }
            }
            catch (Exception err)
            {
                log.Error("Exception in ReceiveEmoticon", err);
                Close(CloseReason.ApplicationError);
            }
        }
        internal void ReceiveAvatar(AvatarTransfer avatar)
        {
            try
            {
                if (avatar == null) throw new ArgumentNullException("msg", "message is null");
                DB.DbManager.StoreAvatar(ChatClient.MemberID, avatar);
                log.Debug(string.Format("Downloaded avatar for {0}", this.ChatClient.Username));
            }
            catch (Exception err)
            {
                log.Error("Exception in ReceiveAvatar", err);
                Close(CloseReason.ApplicationError);
            }
        }

        //public override int GetHashCode()
        //{
        //    return this.ChatClient!=null?this.ChatClient.UserID.GetHashCode():this.SessionID.GetHashCode();
        //}

        //public override bool Equals(object obj)
        //{
        //    return Equals(obj as JiveClientSession);
        //}
        //public bool Equals(JiveClientSession other)
        //{
        //    if (other == null)
        //        return false;
        //    if (this.ChatClient == null || this.ChatClient == null)
        //        return this.Equals(other);
        //    return this.ChatClient.UserID.Equals(other.ChatClient.UserID, StringComparison.InvariantCultureIgnoreCase);
        //}
    }
}
